/*
 * \file XmlPath.cpp
 *
 * \date Created on: Jan 26, 2009
 * \author sarah
 */

#include "XmlPath.h"
#include "XmlDirectory.h"
#include "XmlException.h"

/*!
  \class XmlPath
  \brief The XmlPath class models an identifier for Xml Dnd data.

  In the Dnd application data is stored in a heierarchical fashion in the
  file system underneath a root directory.
 */

/*!
 * \brief Generate a file-system safe name from the data item name.
 * \details Builds a copy of \a name with all space characters replaced by
 * underscores.
 * \param QString name to make safe
 * \returns the resulting path safe name
 */
QString XmlPath::safeDataPathName(const QString &name)
{
    return QString(name).replace(QRegExp("\\W+"), "_");
}

const char *XmlPath::BASE_TYPE_NAMES[] = {
    "Class",
    "Race",
    "Equipment",
    "Feat",
    "Skill",
    "Character"
};

const char *XmlPath::SUB_TYPE_NAMES[] = {
    "Power",
    "Trait",
    "None"
};

XmlPath::XmlPath()
    : mType(XmlPath::CLASS_BASE)
    , mSubType(XmlPath::NO_TYPE)
    , mValid(false)
{
}

XmlPath::XmlPath(XmlPath::BaseTypes base, const QString &baseName)
    : mType(base)
    , mSubType(XmlPath::NO_TYPE)
    , mTypeName(baseName)
    , mValid(true)
{
    Q_ASSERT(!mTypeName.contains(' '));
}

XmlPath::XmlPath(const XmlPath & rhs)
{
    mType = rhs.mType;
    mSubType = rhs.mSubType;
    mTypeName = rhs.mTypeName;
    mObjectName = rhs.mObjectName;
    mValid = rhs.mValid;
}

XmlPath::~XmlPath()
{
}

QDir XmlPath::dir() const
{
    if (!mValid)
        throw XmlException("XmlPath invalid");
    XmlDirectory xmlDir;
    return xmlDir.dataSubDir(*this);
}

QString XmlPath::path() const
{
    QString object = (mSubType == NO_TYPE) ? mTypeName : mObjectName;
    if (object.isEmpty())
        return dir().absolutePath();
    return dir().absoluteFilePath(safeDataPathName(object));
}

XmlPath::BaseTypes XmlPath::type() const
{
    return mType;
}

void XmlPath::setType(XmlPath::BaseTypes mType)
{
    mValid = true;
    this->mType = mType;
}

XmlPath::SubTypes XmlPath::subType() const
{
    return mSubType;
}

QString XmlPath::typeName() const
{
    return mTypeName;
}

void XmlPath::setTypeName(QString typeName)
{
    this->mTypeName = safeDataPathName(typeName);
}

QString XmlPath::objectName() const
{
    return mObjectName;
}

void XmlPath::setSubType(XmlPath::SubTypes subType)
{
    this->mSubType = subType;
}

void XmlPath::setObjectName(QString mObjectName)
{
    this->mObjectName = mObjectName;
}

bool XmlPath::valid() const
{
    if (!mValid)
        return false;
    QString object = (mSubType == XmlPath::NO_TYPE) ? mTypeName : mObjectName;
    if (object.isEmpty())
        return dir().exists();
    return dir().exists(safeDataPathName(object));
}

XmlPath & XmlPath::operator=(const XmlPath & rhs)
{
    mType = rhs.mType;
    mSubType = rhs.mSubType;
    mTypeName = rhs.mTypeName;
    mObjectName = rhs.mObjectName;
    mValid = rhs.mValid;
    return *this;
}
